#include <head.h>

// 定义信号量
sem_t sem;
pthread_mutex_t mutex;
int parking_space = 10;

// 声明线程函数
void *sem_func(void *val);
void *admin_func();

int main(int argc, char const *argv[])
{
    // 定义线程 tid 以及 id
    pthread_t Tid[10], admin_tid;
    int ID_arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // 线程内部使用 展示自己是几号线程
    int __errnum;

    // 初始化信号
    sem_init(&sem, 0, 3); // 设置停车场 一次只能停 3 辆车
    pthread_mutex_init(&mutex, NULL);
    

    if (0 != (__errnum = pthread_create(&admin_tid, NULL, admin_func, NULL)))
    {
        printf("pthread_create error: %d %s\n", __errnum, strerror(__errnum));
    }

    // 创建线程
    for (size_t i = 0; i < 10; i++)
    {
        if (0 != (__errnum = pthread_create(&Tid[i], NULL, sem_func, (void *)&ID_arr[i])))
        {
            printf("pthread_create error: %d %s\n", __errnum, strerror(__errnum));
        }
        // 重置错误码 == 重置 系统中的 error 的值 perror 是可以直接获取的
        // 返回错误码 == 当函数出错时 返回错误码编号 strerror
    }

    // 回收线程
    for (int i = 0; i < 10; i++)
    {
        pthread_join(Tid[i], NULL);
    }

    pthread_join(admin_tid, NULL);

    // 销毁线程
    sem_destroy(&sem);
    pthread_mutex_destroy(&mutex);

    return 0;
}

// 定义线程函数
void *sem_func(void *val)
{
    int id = *((int *)val);
    printf("停车场剩余车位：%d\n", parking_space);
    
    printf("小车 %d 等待车位.....\n", id);
    sem_wait(&sem); // P操作  
    pthread_mutex_lock(&mutex);
    
    // 线程开始工作
    printf("小车 %d 开始停车***>\n", id);
    sleep(2);
    printf("小车 %d 结束停车===>\n", id);
    parking_space--;
    printf("停车场剩余车位：%d\n", parking_space);
    pthread_mutex_unlock(&mutex);
    // V操作
    sem_post(&sem);
    return NULL;
}

void *admin_func()
{
    while (parking_space > 0)
    {
        pthread_mutex_lock(&mutex);
        
        pthread_mutex_unlock(&mutex);
        sleep(1);
    }
    return NULL;
}